package com.bawei.mall.product.service.impl;

import com.fasterxml.jackson.core.type.TypeReference;
import com.alibaba.fastjson.JSON;
import com.bawei.common.core.domain.R;
import com.bawei.common.core.exception.ServiceException;
import com.bawei.common.core.utils.DateUtils;
import com.bawei.common.core.utils.bean.BeanUtils;
import com.bawei.common.rabbit.domain.Message;
import com.bawei.common.rabbit.enums.QueueEnum;
import com.bawei.common.security.utils.SecurityUtils;
import com.bawei.mall.product.cache.ProductInfoCache;
import com.bawei.mall.product.domain.*;
import com.bawei.mall.product.domain.model.ProductModel;
import com.bawei.mall.product.domain.model.SkuModel;
import com.bawei.mall.product.domain.reponse.ProductDetailsResponse;
import com.bawei.mall.product.domain.reponse.ProductInfoResponse;
import com.bawei.mall.product.domain.request.ProductInfoRequest;
import com.bawei.mall.product.mapper.MallProductInfoMapper;
import com.bawei.mall.product.service.*;
import com.bawei.system.domain.CreateEsinfo;
import com.bawei.system.domain.vo.EsDocInsertVo;
import com.bawei.system.remote.api.RemoteEsDocService;
import com.bawei.system.remote.api.RemoteEsIndexService;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.PostConstruct;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;

/**
 * 商品信息Service业务层处理
 *
 * @author DongZeLiang
 * @date 2022-09-19
 */
@Service
@Slf4j
public class MallProductInfoServiceImpl implements IMallProductInfoService {
    @Autowired
    private MallProductInfoMapper mallProductInfoMapper;

    @Autowired
    private IMallProductSkuInfoService skuInfoService;

    @Autowired
    private IMallProductRuleInfoService ruleInfoService;

    @Autowired
    private IMallProductBrandInfoService iMallProductBrandInfoService;

    @Autowired
    private IMallProductTypeInfoService iMallProductTypeInfoService;

    @Autowired
    private IMallProductRuleInfoService iMallProductRuleInfoService;

    @Autowired
    private ProductInfoCache productInfoCache;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private RemoteEsDocService remoteEsDocService;

    @Autowired
    private RemoteEsIndexService remoteEsIndexService;

    @Autowired
    private ResourceLoader resourceLoader;

    private static final String INDEX_NAME="product_sku_info";


    /**
     * 项目启动时，把商品数据初始化到ES中
     */
    @PostConstruct
    public void init() {
        loadingProductInfoToEs();
    }

    /**
     * 查询商品信息
     *
     * @param id 商品信息主键
     * @return 商品信息
     */
    @Override
    public ProductInfoResponse selectMallProductInfoById(Long id) {
        MallProductInfo mallProductInfo = mallProductInfoMapper.selectMallProductInfoById(id);
        ProductInfoResponse productInfoResponse = new ProductInfoResponse();
        BeanUtils.copyBeanProp(productInfoResponse, mallProductInfo);
        productInfoResponse.setSkuInfoList(
                skuInfoService.selectMallProductSkuInfoList(new MallProductSkuInfo() {{
                    setProductId(id);
                }})
        );
        return productInfoResponse;
    }

    @Override
    public ProductDetailsResponse selectProductDetailsById(Long productId) {
        if (productId == null || productId == 0) {
            throw new ServiceException("查询商品信息，依据不合法！");
        }
        ProductDetailsResponse productDetailsResponse = new ProductDetailsResponse();
        ProductModel productModel = mallProductInfoMapper.selectProductModelById(productId);
        if (productModel == null) {
            throw new ServiceException("查询商品信息，商品数据为空");
        }
        productDetailsResponse.setProduct(productModel);
        List<MallProductSkuInfo> mallProductSkuInfos = skuInfoService.selectMallProductSkuInfoList(productId);
        if (mallProductSkuInfos == null || mallProductSkuInfos.size() == 0) {
            throw new ServiceException("查询商品信息，SKU数据为空");
        }
        productDetailsResponse.setSkuList(mallProductSkuInfos);
        MallProductRuleInfo ruleInfo = ruleInfoService.selectMallProductRuleInfoById(productModel.getRuleId());
        if (ruleInfo == null) {
            throw new ServiceException("查询商品信息，规格数据为空");
        }
        productDetailsResponse.setProductRule(ruleInfo);
        return productDetailsResponse;
    }

    /**
     * 查询商品信息列表
     *
     * @param mallProductInfo 商品信息
     * @return 商品信息
     */
    @Override
    public List<MallProductInfo> selectMallProductInfoList(MallProductInfo mallProductInfo) {
        return mallProductInfoMapper.selectMallProductInfoList(mallProductInfo);
    }


    /**
     * 新增商品信息
     *
     * @param productInfoRequest 商品信息
     * @return 结果
     */
    @Override
    @Transactional
    public int insertMallProductInfo(ProductInfoRequest productInfoRequest) {
        productInfoRequest.setCreateBy(String.valueOf(SecurityUtils.getUserId()));
        productInfoRequest.setCreateTime(DateUtils.getNowDate());
        int i = mallProductInfoMapper.insertMallProductInfo(productInfoRequest);
        if (i == 0) {
            return i;
        }

        skuInfoService.batchInsertProductSku(
                SkuModel.builderSkuModel(productInfoRequest.getId(), productInfoRequest.getSkuInfoList())
        );

        // 给搜索系统发送消息需要进行搜索更新
        try {
            rabbitTemplate.convertAndSend(QueueEnum.PRODUCT_ADD.queueName(),
                    Message.builderMsg(productInfoRequest.getId()));
        } catch (ServiceException serviceException) {
            throw new ServiceException("给搜索系统发送消息需要进行搜索更新失败！");
        }
        return i;
    }

    /**
     * 修改商品信息
     *
     * @param productInfoRequest 商品信息
     * @return 结果
     */
    @Override
    @Transactional
    public int updateMallProductInfo(ProductInfoRequest productInfoRequest) {
        productInfoRequest.setUpdateBy(String.valueOf(SecurityUtils.getUserId()));
        productInfoRequest.setUpdateTime(DateUtils.getNowDate());
        int i = mallProductInfoMapper.updateMallProductInfo(productInfoRequest);
        if (i == 0) {
            //将商品信息推送至MQ，异步更新ES
            try {
                rabbitTemplate.convertAndSend(QueueEnum.PRODUCT_ADD.queueName(),
                        Message.builderMsg(productInfoRequest.getId()));
            } catch (ServiceException serviceException) {
                throw new ServiceException("给搜索系统发送消息需要进行搜索更新失败！");
            }
            return i;
        }
        skuInfoService.deleteMallProductSkuInfoByProductId(productInfoRequest.getId());
        skuInfoService.batchInsertProductSku(
                SkuModel.builderSkuModel(productInfoRequest.getId(), productInfoRequest.getSkuInfoList())
        );
        return i;
    }

    /**
     * 批量删除商品信息
     *
     * @param ids 需要删除的商品信息主键
     * @return 结果
     */
    @Override
    public int deleteMallProductInfoByIds(Long[] ids) {
        skuInfoService.deleteMallProductSkuInfoByProductIds(ids);
        for (Long id : ids) {
            // 延迟执行
            productInfoCache.delayRemove(id);
        }
        return mallProductInfoMapper.deleteMallProductInfoByIds(ids);
    }

    /**
     * 删除商品信息信息
     *
     * @param id 商品信息主键
     * @return 结果
     */
    @Override
    public int deleteMallProductInfoById(Long id) {
        return mallProductInfoMapper.deleteMallProductInfoById(id);
    }

    /**
     * 商品总条数
     *
     * @param mallProductInfo 商品查询
     * @return
     */
    @Override
    public Long selectMallProductInfoCount(MallProductInfo mallProductInfo) {
        return mallProductInfoMapper.selectMallProductInfoCount(mallProductInfo);
    }

    /**
     * 商品上下架
     * @param id
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void uploadInfo(Long id,Integer upStatus) {
        if(id==null){
            throw new ServiceException("商品id不能為空");
        }
        //查询商品spu信息
        MallProductInfo mallProductInfo = mallProductInfoMapper.selectMallProductInfoById(id);
        if (mallProductInfo == null) {
            throw new ServiceException("商品信息不存在");
        }
        //修改商品上下架状态
        mallProductInfoMapper.uploadInfo(id,upStatus);
        //查询商品SKU信息
        List<MallProductSkuInfo> mallProductSkuInfos = skuInfoService.selectMallProductSkuInfoList(id);
        if(CollectionUtils.isEmpty(mallProductSkuInfos)){
            throw new ServiceException("该商品id下没有sku信息");
        }
        //上架调用es同步
        if(upStatus==0){
            //参数转换
            List<EsDocInsertVo> list=transFormDate(mallProductInfo,mallProductSkuInfos);
            //调用ES查询商品是否上架
            remoteEsDocService.batchInsertDocs(list);
        }
        //下架调用es同步删除
        if(upStatus==1){
            ArrayList<Integer> idlist = new ArrayList<>();
            Integer[] docIds =null;
            for (MallProductSkuInfo mallProductSkuInfo : mallProductSkuInfos) {
                Long id1 = mallProductSkuInfo.getId();
                idlist.add(id1.intValue());
            }
            docIds=idlist.toArray(new Integer[0]);
            System.out.println("要删除的数组是："+ Arrays.toString(docIds));
            //根据ids删除文档
            remoteEsDocService.deleteDocsById(docIds,INDEX_NAME);
        }
    }


    private List<EsDocInsertVo> transFormDate(MallProductInfo mallProductInfo, List<MallProductSkuInfo> mallProductSkuInfos) {
        //判断索引存不存在
        R<Boolean> booleanR = remoteEsIndexService.indexExit(INDEX_NAME);
        Boolean data = booleanR.getData();
        if(!data){
            //创建索引带有mapping，setting
            //esindexCread();
            remoteEsIndexService.indexCreate(INDEX_NAME);
        }
        //商品id
        Long id = mallProductInfo.getId();
        ArrayList<EsDocInsertVo> list = new ArrayList<>();
        Map<String, Object> map = new HashMap<>();
        //拿来塞图骗中文逗号
        List<String> images = new ArrayList<>();
        String[] split = mallProductInfo.getCarouselImages().split("，");
        //将spu里的图片都塞到一个集合当中
        images.addAll(Arrays.asList(split));
        //商品搜索信息
        ArrayList<String> suggestions = new ArrayList<>();
        //添加搜索suggestions
        suggestions.add(mallProductInfo.getProductDesc());
        suggestions.add(mallProductInfo.getKeywords());
        //查询商品品牌
        MallProductBrandInfo mallProductBrandInfo = iMallProductBrandInfoService.selectMallProductBrandInfoById(Long.valueOf(mallProductInfo.getBrand()));
        if(mallProductBrandInfo!=null){
            map.put("brandName",mallProductBrandInfo.getName());
        }
        //查询商品类型
        MallProductTypeInfo mallProductTypeInfo = iMallProductTypeInfoService.selectMallProductTypeInfoById(Long.valueOf(mallProductInfo.getType()));
        if(mallProductTypeInfo!=null){
            map.put("typeName",mallProductTypeInfo.getName());
        }
        //查询商品规格
        MallProductRuleInfo mallProductRuleInfo = iMallProductRuleInfoService.selectMallProductRuleInfoById(mallProductInfo.getRuleId());
        if(mallProductRuleInfo!=null){
            map.put("ruleName",mallProductRuleInfo.getName());
        }
        for (MallProductSkuInfo mallProductSkuInfo : mallProductSkuInfos) {
            EsDocInsertVo esDocInsertVo = new EsDocInsertVo();
            esDocInsertVo.setId(String.valueOf(mallProductSkuInfo.getId()));
            esDocInsertVo.setIndexName(INDEX_NAME);
            //添加spu
            map.put("name",mallProductInfo.getName());
            map.put("productDesc",mallProductInfo.getProductDesc());
            map.put("keywords",mallProductInfo.getKeywords());
            //添加图片的集合
            map.put("imagesSpu",images);
            //添加商品搜索信息
            map.put("suggestions",suggestions);
            //添加sku
            map.put("productId",mallProductSkuInfo.getProductId());
            map.put("sku",mallProductSkuInfo.getSku());
            map.put("stock",mallProductSkuInfo.getStock());
            map.put("price",mallProductSkuInfo.getPrice());
            map.put("purchasePrice",mallProductSkuInfo.getPurchasePrice());
            map.put("sellingPrice",mallProductSkuInfo.getSellingPrice());
            map.put("number",mallProductSkuInfo.getNumber());
            map.put("weight",mallProductSkuInfo.getWeight());
            map.put("volume",mallProductSkuInfo.getVolume());
            map.put("imageSku",mallProductSkuInfo.getImage());
            esDocInsertVo.setData(map);
            list.add(esDocInsertVo);
        }
        return  list;
    }


//    private void esindexCread() {
//        CreateEsinfo createEsinfo = new CreateEsinfo();
//        Map<String, Object> indexMappings = loadJsonFile("resources:es/product_sku_info_mappings.json");
//        Map<String, Object> indexSettings = loadJsonFile("resources:es/product_sku_info_settings.json");
//
//        createEsinfo.setIndexMappings(indexMappings);
//        createEsinfo.setIndexSettings(indexSettings);
//        createEsinfo.setIndexName(INDEX_NAME);
//        //创建索引
//        remoteEsIndexService.indexCreateWithMapping(createEsinfo);
//    }
//
//
//    private Map<String, Object> loadJsonFile(String path) {
//        try {
//            Resource resource = resourceLoader.getResource(path);
//            String content = new String(Files.readAllBytes(Paths.get(resource.getURI())));
//            // Assuming the file content is a JSON string and converting it to a Map
//            return new ObjectMapper().readValue(content, new TypeReference<Map<String, Object>>() {});
//        } catch (IOException e) {
//            throw new RuntimeException("Failed to read file: " + path, e);
//        }
//    }


    @Override
    public void loadingProductInfoToEs() {
//        //查询所有商品信息
//        List<MallProductInfo> mallProductInfos = mallProductInfoMapper.selectMallProductInfoList(new MallProductInfo());
//        if (mallProductInfos == null || mallProductInfos.size() == 0) {
//            log.info("暂无需要同步的商品");
//        }
//        //调用ES查询索引是否存在
//        R<Boolean> indexExit = remoteEsIndexService.indexExit("mall_product");
//        if (!indexExit.getData()) {
//            log.info("mall_product索引不存在,调用ES服务创建索引");
//            //创建索引
//            R<Boolean> indexCreate = remoteEsIndexService.indexCreate("mall_product");
//            if (!indexCreate.getData()) {
//                log.info("创建mall_product索引失败");
//            }
//            //批量同步商品信息到ES
//            //构建参数
//            List<EsDocInsertVo> esDocInsertVo = builderProductInfoToEs(mallProductInfos);
//            //调用ES服务批量插入文档
//            R<Boolean> batchInsert = remoteEsDocService.batchInsertDocs(esDocInsertVo);
//            if (batchInsert.getData()) {
//                log.info("批量同步商品信息到ES成功");
//            }
//        }
    }



    private List<EsDocInsertVo> builderProductInfoToEs(List<MallProductInfo> mallProductInfos) {
        List<EsDocInsertVo> esDocInsertVos = new ArrayList<>();
        mallProductInfos.stream().forEach(mallProductInfo -> {
            EsDocInsertVo esDocInsertVo = new EsDocInsertVo();
            esDocInsertVo.setId(String.valueOf(mallProductInfo.getId()));
            esDocInsertVo.setIndexName("mall_product");
            //对象转为Map
            Map<String, Object> data = JSON.parseObject(JSON.toJSONString(mallProductInfo), Map.class);
            esDocInsertVo.setData(data);
            esDocInsertVos.add(esDocInsertVo);
        });
        return esDocInsertVos;
    }


    /**
     * 根据品牌id查询商品
     * @param brandId
     * @return
     */
    @Override
    public List<MallProductInfo> listBybrandId(Integer brandId) {
        return mallProductInfoMapper.listBybrandId(brandId);
    }

    @Override
    public List<MallProductInfo> selectList( ) {
        return mallProductInfoMapper.selectList();
    }

    @Override
    public List<MallProductInfo> selectListCommend() {
        return mallProductInfoMapper.selectListCommend();
    }

    @Override
    public List<MallProductInfo> findProductlistByKeyWord(String keywords) {
        return mallProductInfoMapper.findProductlistByKeyWord(keywords);
    }


}
